/**   
 * @Title: BaseDAO.java
 * @Package com.cityoneyes.dao
 * @Description: TODO
 * @author www.momeating.com
 * @date 2011-7-31 下午09:44:33
 * @version V1.0   
 */
package com.momeating.dao;

import java.io.Serializable;
import java.sql.SQLException;
import java.util.Collection;
import java.util.List;

import org.hibernate.HibernateException;
import org.hibernate.LockMode;
import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.dao.support.DataAccessUtils;
import org.springframework.orm.hibernate3.HibernateCallback;
import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
import org.springframework.stereotype.Repository;

import com.cityoneyes.util.PageUtil;

/**
 * @ClassName: BaseDAO
 * @Description: BASE DAO类
 * @author www.momeating.com
 * @date 2011-7-31 下午09:44:33
 */
/**
 * @ClassName: BaseDAO
 * @Description: BASE DAO类
 * @author www.momeating.com
 * @date 2011-7-31 下午09:44:33
 */
@SuppressWarnings("unchecked")
@Repository("baseDao")
public class BaseDAO extends HibernateDaoSupport {
	
	public BaseDAO() {
	}
	
	@Autowired
	public void setSF(SessionFactory sessionFactory) {
		setSessionFactory(sessionFactory);
	}
	
	/**
	 * @Title: buildParameters 
	 * @Description: 组装参数 
	 * @param @param query
	 * @param @param params  
	 * @return void
	 */
	private void buildParameters(Query query, Object[] params) {
		int flag = 0;
		if (params == null || params.length == 0) {
			return;
		}
		for (Object item : params) {
			query.setParameter(flag++, item);
		}
	}

	/**
	 * @Title: saveOrUpdate 
	 * @Description: 新增或更新操作，如果存在ID则更新
	 * @param @param t
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void saveOrUpdate(Object t) throws DataAccessException {
		this.getHibernateTemplate().saveOrUpdate(t);
	}

	/**
	 * @Title: get 
	 * @Description: 根据类和ID获取对象 
	 * @param @param objClass
	 * @param @param id
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return Object
	 */
	public Object get(Class objClass, Serializable id) throws DataAccessException {
		return getHibernateTemplate().get(objClass, id);
	}

	/**
	 * @Title: contains 
	 * @Description: 判断session中是否存在该对象 
	 * @param @param t
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return boolean
	 */
	public boolean contains(Object t) throws DataAccessException {
		return getHibernateTemplate().contains(t);
	}

	/**
	 * @Title: delete 
	 * @Description: 删除对象， 采用加锁机制，对数据安全性要求高的可以采用这个方法
	 * @param @param t
	 * @param @param lockMode
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void delete(Object t, LockMode lockMode) throws DataAccessException {
		getHibernateTemplate().delete(t, lockMode);
	}

	/**
	 * @Title: delete 
	 * @Description: 删除对象 
	 * @param @param t
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void delete(Object t) throws DataAccessException {
		getHibernateTemplate().delete(t);
	}
	
	/**
	 * @Title: delete 
	 * @Description: 根据类名和主键删除，注意：主键属性名必须为id
	 * @param @param objClass
	 * @param @param id  
	 * @return void
	 */
	public void delete(Class objClass, Serializable id) {
		executeUpdate("delete from " + objClass.getName() + " where id=?", id);
	}

	/**
	 * @Title: deleteAll 
	 * @Description: 批量el删除对象集合 
	 * @param @param entities
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void deleteAll(Collection<Object> entities) throws DataAccessException {
		getHibernateTemplate().deleteAll(entities);
	}

	/**
	 * @Title: find 
	 * @Description: 列表查询，只有一个参数的情况 
	 * @param @param queryString
	 * @param @param value
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return List
	 */
	public List find(String queryString, Object value) throws DataAccessException {
		return (List) getHibernateTemplate().find(queryString, value);
	}

	/**
	 * @Title: find 
	 * @Description: 执行HQL查询，参数值采用'?'形式，顺序设置到object数组中
	 * @param @param queryString
	 * @param @param values
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return List
	 */
	public List find(String queryString, Object[] values) throws DataAccessException {
		return (List) getHibernateTemplate().find(queryString, values);
	}

	/**
	 * @Title: find 
	 * @Description: 执行HQL查询，无参数 
	 * @param @param queryString
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return List
	 */
	public List find(String queryString) throws DataAccessException {
		return (List) getHibernateTemplate().find(queryString);
	}
	
	/**
	 * @Title: findAll 
	 * @Description: 查找所有
	 * @param objClass
	 * @return
	 * @throws DataAccessException
	 * @return List
	 */
	public List findAll(Class objClass) throws DataAccessException {
		return (List) getHibernateTemplate().find("from " + objClass.getName());
	}

	/**
	 * @Title: refresh 
	 * @Description: 刷新持久层对象到session缓存，采用加锁机制 
	 * @param @param t
	 * @param @param lockMode
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void refresh(Object t, LockMode lockMode) throws DataAccessException {
		getHibernateTemplate().refresh(t, lockMode);
	}

	/**
	 * @Title: refresh 
	 * @Description: 刷新持久层对象到session缓存 
	 * @param @param t
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void refresh(Object t) throws DataAccessException {
		getHibernateTemplate().refresh(t);
	}

	/**
	 * @Title: save 
	 * @Description: 新增记录 
	 * @param @param t
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return Serializable
	 */
	public Serializable save(Object t) throws DataAccessException {
		return getHibernateTemplate().save(t);
	}

	/**
	 * @Title: saveOrUpdateAll 
	 * @Description: 批量新增或更新（ID存在）记录集合 
	 * @param @param entities
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void saveOrUpdateAll(Collection<Object> entities)
			throws DataAccessException {
		getHibernateTemplate().saveOrUpdateAll(entities);
	}

	/**
	 * @Title: update 
	 * @Description: 更新操作，采用加锁机制 
	 * @param @param t
	 * @param @param lockMode
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void update(Object t, LockMode lockMode) throws DataAccessException {
		getHibernateTemplate().update(t, lockMode);
	}

	/**
	 * @Title: update 
	 * @Description: 更新操作 
	 * @param @param t
	 * @param @throws DataAccessException  
	 * @return void
	 */
	public void update(Object t) throws DataAccessException {
		getHibernateTemplate().update(t);
	}

	/**
	 * @Title: findByExample 
	 * @Description: 根据对象example查询 ，简单的查询可以采用该方法，不用写HQL，
	 * 				避免属性名修改带来的隐性错误，仅限于做=查询，不支持排序控制
	 * @param @param t
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return List
	 */
	public List findByExample(Object t) throws DataAccessException {
		return getHibernateTemplate().findByExample(t);
	}
	
	/**
	 * @Title: findByExample 
	 * @Description: 根据对象example查询，设置分页，简单的查询可以采用该方法，不用写HQL，
	 * 				避免属性名修改带来的隐性错误，仅限于做=查询，不支持排序控制
	 * @param @param t
	 * @param @param startIndex
	 * @param @param size
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return List
	 */
	public List findByExample(Object t, int startIndex, int size) throws DataAccessException {
		return getHibernateTemplate().findByExample(t, startIndex, size);
	}

	/**
	 * @Title: findByCriteria 
	 * @Description: 根据DetachedCriteria动态组装HQL查询
	 * @param @param criteria
	 * @param @return  
	 * @return List
	 */
	public List findByCriteria(DetachedCriteria criteria) {
		return getHibernateTemplate().findByCriteria(criteria);
	}
	
	/**
	 * @Title: findByCriteria 
	 * @Description: 根据DetachedCriteria动态组装HQL分页查询， 
	 * @param @param criteria
	 * @param @param startIndex
	 * @param @param size
	 * @param @return  
	 * @return List
	 */
	public List findByCriteria(DetachedCriteria criteria, int startIndex, int size) {
		return getHibernateTemplate().findByCriteria(criteria, startIndex, size);
	}

	/**
	 * @Title: findPageByQuery 
	 * @Description: 分页查询，无hql参数 
	 * @param @param hql
	 * @param @param pageSize
	 * @param @param startIndex
	 * @param @return  
	 * @return List
	 */
	public List findPageByQuery(final String hql, final int pageSize, final int startIndex) {
		return (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						query.setFirstResult(startIndex);
						query.setMaxResults(pageSize);
						return query.list();
					}
				});
	}

	/**
	 * @Title: findPageByQuery 
	 * @Description: 分页查询，只有一个参数 
	 * @param @param hql
	 * @param @param param
	 * @param @param pageSize
	 * @param @param startIndex
	 * @param @return  
	 * @return List
	 */
	public List findPageByQuery(final String hql, final Object param, final int pageSize, final int startIndex) {
		return (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						query.setParameter(0, param);
						query.setFirstResult(startIndex);
						query.setMaxResults(pageSize);
						return query.list();
					}
				});
	}

	/**
	 * @Title: findPageByQuery 
	 * @Description: 分页查询，提供参数集合 
	 * @param @param hql
	 * @param @param params
	 * @param @param pageSize
	 * @param @param startIndex
	 * @param @return  
	 * @return List
	 */
	public List findPageByQuery(final String hql, final Object[] params, final int pageSize, final int startIndex) {
		return (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						// 组建参数
						buildParameters(query, params);
						query.setFirstResult(startIndex);
						query.setMaxResults(pageSize);
						return query.list();
					}
				});
	}

	/**
	 * @Title: findPageByQuery 
	 * @Description: 分页查询，加入PageUtil工具类 
	 * @param @param hql
	 * @param @param page
	 * @param @param params
	 * @param @return  
	 * @return List
	 */
	public List findPageByQuery(final String hql, final PageUtil page, final Object[] params) {
		return (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						page.setTotalCount(countByHql("select count(*) " + hql.substring(hql.toLowerCase().indexOf("from")), params));
						Query query = session.createQuery(hql);
						// 组建参数
						buildParameters(query, params);
						query.setFirstResult(page.getFirstResult());
						query.setMaxResults(page.getPageSize());
						return query.list();
					}
				});
	}

	/**
	 * @Title: executeUpdate 
	 * @Description: 执行HQL更新操作，无参数情况 
	 * @param @param hql
	 * @param @return  
	 * @return int
	 */
	public int executeUpdate(final String hql) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						return query.executeUpdate();
					}
				});
	}

	/**
	 * @Title: executeUpdate 
	 * @Description: 执行HQL更新操作，一个参数情况 
	 * @param @param hql
	 * @param @param param
	 * @param @return  
	 * @return int
	 */
	public int executeUpdate(final String hql, final Object param) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						query.setParameter(0, param);
						return query.executeUpdate();
					}
				});
	}

	/**
	 * @Title: executeUpdate 
	 * @Description: 执行HQL更新操作，多个参数情况 
	 * @param @param hql
	 * @param @param params
	 * @param @return  
	 * @return int
	 */
	public int executeUpdate(final String hql, final Object[] params) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						Query query = session.createQuery(hql);
						buildParameters(query, params);
						return query.executeUpdate();
					}
				});
	}
	
	/**
	 * @Title: count
	 * @Description: 统计表记录数量
	 * @param objClass
	 * @return
	 * @throws DataAccessException
	 * @return int
	 */
	public int count(Class objClass) throws DataAccessException {
		return DataAccessUtils.intResult(getHibernateTemplate().find("select count(*) from " + objClass.getName()));
	}
	
	/**
	 * @Title: countByHql 
	 * @Description: 根据HQL统计查询结果数，无参数调用 
	 * @param @param hql
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return int
	 */
	public int countByHql(String hql) throws DataAccessException {
		return DataAccessUtils.intResult(getHibernateTemplate().find(hql));
	}

	/**
	 * @Title: countByHql 
	 * @Description: 根据HQL统计查询结果数，一个参数调用  
	 * @param @param hql
	 * @param @param param
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return int
	 */
	public int countByHql(String hql, Object param) throws DataAccessException {
		return DataAccessUtils.intResult(getHibernateTemplate().find(hql, param));
	}
	
	/**
	 * @Title: countByHql 
	 * @Description: 根据HQL统计查询结果数，多个参数调用  
	 * @param @param hql
	 * @param @param params
	 * @param @return
	 * @param @throws DataAccessException  
	 * @return int
	 */
	public int countByHql(String hql, Object[] params) throws DataAccessException {
		return DataAccessUtils.intResult(getHibernateTemplate().find(hql, params));
	}

	/**
	 * @Title: executeSQLUpdate 
	 * @Description: 执行SQL更新操作，无参数情况 
	 * @param @param sql
	 * @param @return  
	 * @return int
	 */
	public int executeSQLUpdate(final String sql) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						SQLQuery query = session.createSQLQuery(sql);
						return query.executeUpdate();
					}
				});
	}

	/**
	 * @Title: executeSQLUpdate 
	 * @Description: 执行SQL更新操作，一个参数情况 
	 * @param @param sql
	 * @param @param param
	 * @param @return  
	 * @return int
	 */
	public int executeSQLUpdate(final String sql, final Object param) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						SQLQuery query = session.createSQLQuery(sql);
						query.setParameter(0, param);
						return query.executeUpdate();
					}
				});
	}

	/**
	 * @Title: executeSQLUpdate 
	 * @Description: 执行SQL更新操作，多个参数情况 
	 * @param @param sql
	 * @param @param params
	 * @param @return  
	 * @return int
	 */
	public int executeSQLUpdate(final String sql, final Object[] params) {
		return (Integer) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						SQLQuery query = session.createSQLQuery(sql);
						buildParameters(query, params);
						return query.executeUpdate();
					}
				});
	}

	/**
	 * @Title: executeSQLQuery 
	 * @Description: 执行SQL查询，无参数调用
	 * @param @param sql
	 * @param @return  
	 * @return List
	 */
	public List executeSQLQuery(final String sql) {
		return (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						SQLQuery query = session.createSQLQuery(sql);
						return query.list();
					}
				});
	}

	/**
	 * @Title: executeSQLQuery 
	 * @Description: 执行SQL查询，一个参数调用 
	 * @param @param sql
	 * @param @param param
	 * @param @return  
	 * @return List
	 */
	public List executeSQLQuery(final String sql, final Object param) {
		return (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						SQLQuery query = session.createSQLQuery(sql);
						query.setParameter(0, param);
						return query.list();
					}
				});
	}

	/**
	 * @Title: executeSQLQuery 
	 * @Description: 执行SQL查询，多个参数调用 
	 * @param @param sql
	 * @param @param params
	 * @param @return  
	 * @return List
	 */
	public List executeSQLQuery(final String sql, final Object[] params) {
		return (List) getHibernateTemplate().execute(
				new HibernateCallback() {
					public Object doInHibernate(Session session) throws HibernateException, SQLException {
						SQLQuery query = session.createSQLQuery(sql);
						buildParameters(query, params);
						return query.list();
					}
				});
	}
}